package com.example.springboot.service;

import com.example.springboot.dto.*;
import com.example.springboot.entity.*;
import com.example.springboot.entity.Package;
import com.example.springboot.mapper.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.security.Timestamp;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

@Service
public class OrderService {

    @Autowired
    private DeviceService deviceService;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private MerchantMapper merchantMapper;

    @Autowired
    private PaymentMapper paymentMapper;

    @Autowired
    private PackageMapper packageMapper;

    @Autowired
    private OptionPriceMapper optionPriceMapper;

    @Autowired
    private ClothingRentalMapper clothingRentalMapper;

    @Transactional
    public Order createOrderAndPayment(OrderRequest request) {
        if (request.getMerchantId() != null) {
            return createMerchantOrder(request);
        }
        // 检查设备状态
        Device device = deviceService.getDeviceStatus(request.getDeviceId());
        if (device == null || !"available".equals(device.getStatus())) {
            throw new RuntimeException("设备不可用");
        }

        // 创建订单对象
        Order order = new Order();
        order.setDeviceId(request.getDeviceId());
        order.setUserId(request.getUserId());
        order.setStatus("pending"); // 初始状态为 pending
        order.setCreatedAt(LocalDateTime.now());
        order.setUpdatedAt(LocalDateTime.now());

        BigDecimal orderAmount;
        int totalDuration;

        // 判断 orderType，默认是 merchant_service，若符合自助服务条件，则设置为 self_service
        String orderType = "merchant_service"; // 默认类型是 merchant_service

        // 只允许选择套餐或自定义选项其中之一
        if (request.getPackageId() != null && request.getCustomOptions() != null) {
            throw new RuntimeException("只能选择套餐或自定义选项，不能同时选择");
        } else if (request.getPackageId() != null) {
            // 用户选择了套餐
            order.setPackageId(request.getPackageId());
            orderAmount = packageMapper.getPackagePrice(request.getPackageId()); // 套餐价格
            totalDuration = packageMapper.getPackageDuration(request.getPackageId()); // 套餐时长
        } else if (request.getCustomOptions() != null) {
            // 用户选择了自定义选项
            OrderRequest.CustomOptions customOptions = request.getCustomOptions();
            orderAmount = calculateCustomOptionPrice(customOptions); // 自定义选项价格
            totalDuration = calculateCustomOptionDuration(customOptions); // 自定义选项时长

            // 保存自定义选项 ID 到订单
            order.setWaterOptionId(customOptions.getWaterOptionId());
            order.setProgramOptionId(customOptions.getProgramId());
            order.setScentOptionId(customOptions.getScentId());
            order.setDryingOptionId(customOptions.getDryingId());
        } else {
            throw new RuntimeException("订单选项无效，请选择套餐或自定义选项");
        }

        // 如果是自助服务（套餐或自定义选项），设置为 self_service
        if (request.getPackageId() != null || request.getCustomOptions() != null) {
            orderType = "self_service";
        }

        order.setOrderAmount(orderAmount);
        order.setDuration(totalDuration); // 设置订单总时长
        order.setOrderType(orderType); // 设置订单类型
        order.setPointId(request.getPointId());

        // 保存订单
        orderMapper.insert(order);

        // 更新设备状态为使用中
        deviceService.updateDeviceStatus(request.getDeviceId(), "in_use");

        return order;
    }

    public void updateOrderStatusToWashing(String transactionId) {
        // 查找支付记录
        Payment payment = paymentMapper.findByTransactionId(transactionId);
        if (payment == null || !"success".equals(payment.getPaymentStatus())) {
            throw new RuntimeException("支付未成功");
        }

        // 查找订单
        Order order = orderMapper.findSOById(payment.getOrderId());
        if (order == null) {
            throw new RuntimeException("未找到订单");
        }

        // 更新订单状态为 "washing"
        order.setStatus("washing");
        order.setUpdatedAt(LocalDateTime.now());
        orderMapper.selfupdate(order);

        // 开始倒计时
        startCountdown(order);
    }
//    public void updateOrderStatusToPickedUp(String transactionId) {
//        // 查找支付记录
//        Payment payment = paymentMapper.findByTransactionId(transactionId);
//        if (payment == null || !"success".equals(payment.getPaymentStatus())) {
//            throw new RuntimeException("支付未成功");
//        }
//
//        // 查找订单
//        Order order = orderMapper.findSOById(payment.getOrderId());
//        if (order == null) {
//            throw new RuntimeException("未找到订单");
//        }
//
//        // 更新订单状态为 "ready_for_pickup"
//        order.setStatus("ready_for_pickup");
//        order.setUpdatedAt(LocalDateTime.now());
//        orderMapper.merchantupdate(order);
//    }

    public void updateMOrderStatusToPickedUp(String transactionId) {
        // 查找支付记录
        Payment payment = paymentMapper.findByTransactionId(transactionId);
        if (payment == null || !"success".equals(payment.getPaymentStatus())) {
            throw new RuntimeException("支付未成功");
        }

        // 查找订单
        Order order = orderMapper.findMOById(payment.getOrderId());
        if (order == null) {
            throw new RuntimeException("未找到订单");
        }

        order.setStatus("in_progress");
        order.setUpdatedAt(LocalDateTime.now());
        orderMapper.merchantupdate(order);
    }
    public void startRentalCountdown(Integer orderId, BigDecimal rentalDuration) {
        if (orderId == null || rentalDuration.compareTo(BigDecimal.ZERO) <= 0) {
            throw new IllegalArgumentException("订单ID不能为空，且租用时间必须大于0");
        }

        // 设置倒计时，rentalDuration 单位为小时
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                Order order = findMOrdersById(orderId);
                if (order != null && "rentalling".equals(order.getStatus())) {
                    order.setStatus("to_be_returned");
                    updateMerchantOrder(order);
                }
            }
        }, rentalDuration.multiply(BigDecimal.valueOf(3600000L)).longValue());
    }

    private void startCountdown(Order order) {
        int totalDuration = order.getDuration();

        // 使用 Timer 定时器进行倒计时
        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                // 更新订单状态为 "ready_for_pickup"
                order.setStatus("ready_for_pickup");
                order.setUpdatedAt(LocalDateTime.now());
                orderMapper.selfupdate(order);
            }
        }, totalDuration * 60 * 1000L); // 将时长转换为毫秒
    }

    private BigDecimal calculateCustomOptionPrice(OrderRequest.CustomOptions customOptions) {
        BigDecimal total = BigDecimal.ZERO;
        if (customOptions.getWaterOptionId() != null) {
            total = total.add(optionPriceMapper.getWaterOptionPrice(customOptions.getWaterOptionId()));
        }
        if (customOptions.getProgramId() != null) {
            total = total.add(optionPriceMapper.getProgramOptionPrice(customOptions.getProgramId()));
        }
        if (customOptions.getScentId() != null) {
            total = total.add(optionPriceMapper.getScentOptionPrice(customOptions.getScentId()));
        }
        if (customOptions.getDryingId() != null) {
            total = total.add(optionPriceMapper.getDryingOptionPrice(customOptions.getDryingId()));
        }
        return total;
    }

    private int calculateCustomOptionDuration(OrderRequest.CustomOptions customOptions) {
        int totalDuration = 0;
        if (customOptions.getProgramId() != null) {
            totalDuration += optionPriceMapper.getProgramOptionDuration(customOptions.getProgramId());
        }
        if (customOptions.getDryingId() != null) {
            totalDuration += optionPriceMapper.getDryingOptionDuration(customOptions.getDryingId());
        }
        return totalDuration;
    }

    public void updateOrderStatusToCompleted(Integer orderId) {
        Order order = orderMapper.findSOById(orderId);
        if (order == null) {
            throw new RuntimeException("未找到订单");
        }

        order.setStatus("completed");
        order.setUpdatedAt(LocalDateTime.now());
        orderMapper.selfupdate(order);
    }

    public void updateMerchantOrder(Order order) {
        if (order == null) {
            throw new RuntimeException("未找到订单");
        }
        order.setUpdatedAt(LocalDateTime.now());
        orderMapper.merchantupdate(order);
    }




    public Order findSOrderById(Integer orderId) {
        return orderMapper.findSOById(orderId);
    }
    public Order findMOrdersById(Integer userId) {
        return orderMapper.findMOById(userId);
        }
    public OptionResponse getAllOptions() {
        // 获取所有套餐和选项
        List<Package> packages = packageMapper.getAllPackages();  // 获取所有套餐
        List<Option> waterOptions = optionPriceMapper.getAllWaterOptions();  // 获取水量选项
        List<Option> programOptions = optionPriceMapper.getAllProgramOptions();  // 获取洗衣程序选项
        List<Option> scentOptions = optionPriceMapper.getAllScentOptions();  // 获取香味选项
        List<Option> dryingOptions = optionPriceMapper.getAllDryingOptions();  // 获取烘干选项

        // 返回 OptionResponse 对象
        return new OptionResponse(packages, waterOptions, programOptions, scentOptions, dryingOptions);
    }
    public OrderDetailsResponse getOrderDetails(Integer orderId, Integer userId, String orderType) {
        // 根据订单类型查询订单
        Order order = null;
        if ("self_service".equals(orderType)) {
            order = orderMapper.findSOById(orderId);
        } else if ("merchant_service".equals(orderType)) {
            order = orderMapper.findMOById(orderId);
        }

        // 订单不存在或用户ID不匹配
        if (order == null || !order.getUserId().equals(userId)) {
            return null;
        }

        // 查询支付信息
        Payment payment = paymentMapper.findByOrderIdAndType(orderId,orderType);

        // 构建订单详情响应对象
        OrderDetailsResponse response = new OrderDetailsResponse();
        response.setOrderId(order.getOrderId());
        response.setUserId(order.getUserId());
        response.setOrderAmount(order.getOrderAmount().doubleValue());
        response.setStatus(order.getStatus());
        response.setCreatedAt(order.getCreatedAt().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        response.setUpdatedAt(order.getUpdatedAt().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        response.setPaymentStatus(payment != null ? payment.getPaymentStatus() : "未支付");
        response.setPaymentMethod(payment != null ? payment.getPaymentMethod() : "无");
        response.setTransactionId(payment != null ? payment.getTransactionId() : null);
        response.setOrderType(orderType);

        // 处理不同订单类型的额外字段
        if ("self_service".equals(orderType)) {
            response.setDeviceId(order.getDeviceId());
            response.setPackageId(order.getPackageId());
            response.setWaterOptionId(order.getWaterOptionId());
            response.setProgramId(order.getProgramId());
            response.setScentId(order.getScentId());
            response.setDryingId(order.getDryingId());
            response.setDuration(order.getDuration());
        } else if ("merchant_service".equals(orderType)) {
            response.setMerchantId(order.getMerchantId());
            response.setServiceType(order.getServiceType());
            response.setAddress(order.getAddress());
            response.setContactNumber(order.getContactNumber());
            response.setRentalDuration(order.getRentalDuration());
            response.setAddressLatitude(order.getAddressLatitude());
            response.setAddressLongitude(order.getAddressLongitude());
        }

        return response;
    }

    // 新增商家订单创建方法
    private Order createMerchantOrder(OrderRequest request) {
        // 验证必要字段
        if (!"washing_pickup_only".equals(request.getServiceType()) &&
                !"washing_full_service".equals(request.getServiceType())) {
            throw new RuntimeException("Invalid service type");
        }
        if (request.getAddress() == null || request.getContactNumber() == null) {
            throw new RuntimeException("Address and contact number are required");
        }

        // 获取商家的经纬度
        Merchant merchant = merchantMapper.selectById(request.getMerchantId());
        if (merchant == null) {
            throw new RuntimeException("Merchant not found");
        }

        // 计算距离
        double userLatitude = request.getAddressLatitude();
        double userLongitude = request.getAddressLongitude();
        double merchantLatitude = merchant.getLatitude();
        double merchantLongitude = merchant.getLongitude();

        double distance = calculateDistance(userLatitude, userLongitude, merchantLatitude, merchantLongitude);

        // 计算上门费用
        BigDecimal pickupFee = calculatePickupFee(distance);
        if ("washing_full_service".equals(request.getServiceType())) {
            pickupFee = pickupFee.multiply(new BigDecimal("2"));
        }

        // 创建订单对象
        Order order = new Order();
        order.setUserId(request.getUserId());
        order.setMerchantId(request.getMerchantId());
        order.setServiceType(request.getServiceType());
        order.setAddress(request.getAddress());
        order.setContactNumber(request.getContactNumber());
        order.setOrderAmount(pickupFee); // 确保是数字类型的 BigDecimal
        order.setStatus("pending");
        order.setCreatedAt(LocalDateTime.now());
        order.setUpdatedAt(LocalDateTime.now());
        order.setAddressLatitude(request.getAddressLatitude());
        order.setAddressLongitude(request.getAddressLongitude());

        // 插入商家订单
        orderMapper.insertMerchantOrder(order);

        // 创建支付记录
        Payment payment = new Payment();
        payment.setUserId(request.getUserId());
        payment.setOrderId(order.getOrderId());
        payment.setOrderType("merchant_service");
        payment.setMerchantId(request.getMerchantId());
        payment.setOrderAmount(pickupFee); // 确保是数字类型的 BigDecimal
        payment.setPaymentMethod(request.getPaymentMethod());
        payment.setTransactionId("TXN_M_" + order.getOrderId());
        payment.setPaymentStatus("pending");
        payment.setCreatedAt(LocalDateTime.now());
        payment.setUpdatedAt(LocalDateTime.now());
        paymentMapper.insert(payment);

        return order;
    }


    // 计算两个经纬度之间的距离（单位：公里）
    private double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
        final int R = 6371; // 地球半径，单位：公里

        double latDistance = Math.toRadians(lat2 - lat1);
        double lonDistance = Math.toRadians(lon2 - lon1);
        double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2)
                + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2))
                * Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        double distance = R * c;

        return distance;
    }

    // 计算上门费用
    private BigDecimal calculatePickupFee(double distance) {
        BigDecimal baseFee = new BigDecimal("1.0"); // 3公里内费用
        BigDecimal additionalFeePerKm = new BigDecimal("0.8"); // 超过3公里每公里费用

        if (distance <= 3) {
            return baseFee;
        } else {
            BigDecimal additionalDistance = new BigDecimal(String.valueOf(distance - 3));
            return baseFee.add(additionalDistance.multiply(additionalFeePerKm));
        }
    }


    @Transactional
    public Order createRentalOrder(RentalOrderRequest request) {
        // 检查 rental_id 是否为空
        if (request.getRentalId() == null || request.getRentalId().isEmpty()) {
            throw new RuntimeException("租赁ID不能为空");
        }

        // 拆分 rental_id
        String[] rentalIds = request.getRentalId().split(",");
        BigDecimal totalOrderAmount = BigDecimal.ZERO;

        // 遍历每个 rental_id，检查库存并计算基础金额
        for (String rentalIdStr : rentalIds) {
            int rentalId = Integer.parseInt(rentalIdStr.trim());

            // 获取租赁信息
            ClothingRental rental = clothingRentalMapper.findById(String.valueOf(rentalId));
            if (rental == null) {
                throw new RuntimeException("租赁信息未找到，rental_id: " + rentalId);
            }

            // 检查库存是否足够
            if (rental.getQuantity() < 1) {
                throw new RuntimeException("租赁项ID " + rentalId + " 库存不足，无法租赁");
            }

            // 扣减库存
            int rowsAffected = clothingRentalMapper.decreaseQuantity(rentalId, 1);
            if (rowsAffected == 0) {
                throw new RuntimeException("租赁项ID " + rentalId + " 库存不足，无法租赁");
            }

            // 计算基础金额
            BigDecimal pricePerHour = rental.getPricePerHour();
            BigDecimal rentalDurationInHours = request.getRentalDuration();
            BigDecimal orderAmount = pricePerHour.multiply(rentalDurationInHours);
            totalOrderAmount = totalOrderAmount.add(orderAmount);
        }

        // 根据 serviceType 计算上门费用并调整订单总金额
        if ("rental_pickup_only".equals(request.getServiceType()) || "rental_full_service".equals(request.getServiceType())) {
            // 验证地址和经纬度是否为空
            if (request.getAddress() == null || request.getAddressLatitude() == null || request.getAddressLongitude() == null) {
                throw new RuntimeException("地址和经纬度信息不能为空");
            }

            // 获取商家的经纬度
            Merchant merchant = merchantMapper.selectById(request.getMerchantId());
            if (merchant == null) {
                throw new RuntimeException("商家未找到");
            }

            // 计算距离
            double userLatitude = request.getAddressLatitude();
            double userLongitude = request.getAddressLongitude();
            double merchantLatitude = merchant.getLatitude();
            double merchantLongitude = merchant.getLongitude();
            double distance = calculateDistance(userLatitude, userLongitude, merchantLatitude, merchantLongitude);

            // 计算上门费用
            BigDecimal pickupFee = calculatePickupFee(distance);

            // 根据服务类型调整上门费用
            if ("rental_full_service".equals(request.getServiceType())) {
                pickupFee = pickupFee.multiply(new BigDecimal("2")); // 全程服务上门费用翻倍
            }

            // 将上门费用加到总金额上
            totalOrderAmount = totalOrderAmount.add(pickupFee);
        }

        // 创建订单对象
        Order order = new Order();
        order.setUserId(request.getUserId());
        order.setMerchantId(request.getMerchantId());
        order.setServiceType(request.getServiceType());
        order.setOrderAmount(totalOrderAmount); // 设置总金额（包括上门费用）
        order.setStatus("pending");
        order.setAddress(request.getAddress());
        order.setContactNumber(request.getContactNumber());
        order.setRentalDuration(request.getRentalDuration());
        order.setAddressLatitude(request.getAddressLatitude());
        order.setAddressLongitude(request.getAddressLongitude());
        order.setRentalId(request.getRentalId()); // 保存原始 rental_id 字符串
        order.setCreatedAt(LocalDateTime.now());
        order.setUpdatedAt(LocalDateTime.now());

        // 插入订单记录
        orderMapper.rentalinsert(order);

        // 检查生成的订单ID
        if (order.getOrderId() == null) {
            throw new RuntimeException("订单创建失败，未能生成有效的 orderId");
        } else {
            System.out.println("生成的订单ID: " + order.getOrderId());
        }

        return order;
    }
    public List<Order> getSelfServiceOrdersByUserId(Integer userId) {
        return orderMapper.findSelfServiceOrdersByUserId(userId);
    }

    public List<Order> getMerchantOrdersByUserId(Integer userId) {
        return orderMapper.findMerchantOrdersByUserId(userId);
    }

}